package Model;

import java.util.ArrayList;
import java.util.List;

import Model.alignments.CollapsedAlignment;
import Model.alignments.IntronAlignment;
import Model.alignments.IntronCollapsedAlignment;
import Model.alignments.SpliceAlignment;
import Model.alignments.SpliceCollapsedAlignment;
import Model.alignments.Subset0Alignment;

/**
 * Used in the Subset0Viewport to keep track of valid positions of the graph.
 * 
 * @author stephenbwilliamson
 * 
 */
public class Line {

	private static int maxID = 0;
	private int id = 0;
	private List<Subset0Alignment> taken = null;

	public Line() {
		this.id = ++maxID;
		this.taken = new ArrayList<Subset0Alignment>();
	}

	public Line(int id) {
		if (id > maxID)
			maxID = id;

		this.id = id;
		this.taken = new ArrayList<Subset0Alignment>();
	}

	public static void resetMaxID() {
		maxID = 0;
	}

	public static int getMaxID() {
		return maxID;
	}

	public int getID() {
		return id;
	}

	public boolean collapseAlignments(Subset0Alignment a) {
		Subset0Alignment intersection = null;
		for (Subset0Alignment alignment : taken) {
			ValidPosition position = alignment.getMaxBound();
			if (position.intersects(a.getMaxBound())) {
				intersection = alignment;
				break;
			}
		}
		// Could not find a place where it intersects, therefore it's not
		// collapsible
		if (intersection == null
				|| !CollapsedAlignment.isCandidateAddition(intersection, a))
			return false;

		// Create a collapsed alignment object to combine the two alignment
		CollapsedAlignment cluster = null;
		if (intersection instanceof CollapsedAlignment) {
			cluster = (CollapsedAlignment) intersection;
		}
		if (cluster == null) {
			if (intersection instanceof IntronAlignment)
				cluster = new IntronCollapsedAlignment(intersection);
			else if (intersection instanceof SpliceAlignment)
				cluster = new SpliceCollapsedAlignment(intersection);
			else
				System.out
						.println("Intersection wasn't intron or splice site..");
		}

		cluster.addAlignment(a);

		taken.remove(intersection);
		taken.add(cluster);

		return true;
	}

	public boolean isLoadable(Subset0Alignment a) {
		if (a == null)
			return false;

		for (Subset0Alignment alignment : taken) {
			ValidPosition position = alignment.getMaxBound();
			if (position.intersects(a.getMaxBound()))
				return false;
		}
		return true;
	}

	public List<Subset0Alignment> getAlignments() {
		return taken;
	}

	public void addPosition(Subset0Alignment vp) {
		taken.add(vp);
	}

}
